/* combinatorics.cpp
Michael Zahniser, 12/12/09

Function definitions for the combinatorics operators.
*/

#include "Operators.h"

#include "_common/mz_math.h"

using std::string;


namespace {
	string Factorial = "factorial !";
	static const Do<Factorial> factorial;

	string Choose = "combinations choose c";
	static const Do<Choose> choose_op;

	string Permute = "permutations permute p";
	static const Do<Permute> permute_op;

	string Select = "select s";
	static const Do<Select> select_op;
}



template <> void Do<Factorial>::operator()(State &state) const
{
	long long n = state.PopInt();
	
	double result = 1.;
	for( ; n > 1; --n)
		result *= n;
	
	state.Push(result);
}



template <> void Do<Choose>::operator()(State &state) const
{
	long long k = state.PopInt();
	long long n = state.PopInt();
	
	state.Push(choose(n, k));
}



template <> void Do<Permute>::operator()(State &state) const
{
	long long k = state.PopInt();
	long long n = state.PopInt();
	
	state.Push(permute(n, k));
}



template <> void Do<Select>::operator()(State &state) const
{
	long long k = state.PopInt();
	long long n = state.PopInt();
	
	state.Push(choose(n + k - 1, k));
}
